home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / main / ds3100.md / mainInit.c < prev    next >
C/C++ Source or Header  |  1991-05-30  |  13KB  |  513 lines

  1. /* 
  2.  *  main.c --
  3.  *
  4.  *    The main program for Sprite: initializes modules and creates
  5.  *    system processes. Also creates a process to run the Init program.
  6.  *
  7.  * Copyright 1984 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/kernel/main/ds3100.md/RCS/mainInit.c,v 9.11 91/05/30 13:20:40 shirriff Exp $ SPRITE (DECWRL)";
  19. #endif /* !lint */
  20.  
  21. #include <sprite.h>
  22. #include <dbg.h>
  23. #include <dev.h>
  24. #include <net.h>
  25. #include <proc.h>
  26. #include <prof.h>
  27. #include <fsutil.h>
  28. #include <recov.h>
  29. #include <rpc.h>
  30. #include <sched.h>
  31. #include <sig.h>
  32. #include <sync.h>
  33. #include <sys.h>
  34. #include <timer.h>
  35. #include <vm.h>
  36. #include <machMon.h>
  37. #include <mach.h>
  38. #include <fs.h>
  39. #include <main.h>
  40. #include <stdio.h>
  41.  
  42. static void Init _ARGS_((void));
  43.  
  44. /*
  45.  *  Pathname of the Init program.
  46.  */
  47. #define INIT         "cmds/initsprite"
  48.  
  49. int main_PrintInitRoutines = FALSE;/* print out each routine as it's called? */
  50. int main_PanicOK = 0;    /* Set to 1 if it's OK to panic. */
  51.  
  52. /*
  53.  *----------------------------------------------------------------------
  54.  *
  55.  * main --
  56.  *
  57.  *    All kernel modules are initialized by calling their *_Init()
  58.  *    routines. In addition, kernel processes are created to
  59.  *    handle virtual memory and rpc-specific stuff. The last process
  60.  *    created runs the `init' program.
  61.  *
  62.  * Results:
  63.  *    None.
  64.  *
  65.  * Side effects:
  66.  *    The whole system is initialized.
  67.  *
  68.  *----------------------------------------------------------------------
  69.  */
  70.  
  71. void
  72. main(argc,argv)
  73. int argc;
  74. MachStringTable *argv;
  75. {
  76.     Proc_PID    pid;
  77.     int        i;
  78.  
  79.     /*
  80.      * Initialize variables specific to a given kernel.  
  81.      * IMPORTANT: Only variable assignments and nothing else can be
  82.      *          done in this routine.
  83.      */
  84.     Main_InitVars();
  85.  
  86.     /*
  87.      * Initialize machine dependent info.  MUST BE CALLED HERE!!!.
  88.      */
  89.     if (main_PrintInitRoutines) {
  90.     Mach_MonPrintf("Calling Mach_Init().\n");
  91.     }
  92.     Mach_Init(argc, argv);
  93.  
  94.     /*
  95.      * Initialize variables again, since Mach_Init clobbered them.
  96.      */
  97.     Main_InitVars();
  98.  
  99.     if (main_PrintInitRoutines) {
  100.     Mach_MonPrintf("Calling Sync_Init().\n");
  101.     }
  102.     Sync_Init();
  103.  
  104.     /*
  105.      * Initialize the debugger.
  106.      */
  107.     if (main_PrintInitRoutines) {
  108.     Mach_MonPrintf("Calling Dbg_Init().\n");
  109.     }
  110.     Dbg_Init();
  111.  
  112.     /*
  113.      * Initialize the system module, particularly the fact that there is an
  114.      * implicit DISABLE_INTR on every processor.
  115.      */
  116.     if (main_PrintInitRoutines) {
  117.     Mach_MonPrintf("Calling Sys_Init().\n");
  118.     }
  119.     Sys_Init();
  120.  
  121.     /*
  122.      * Now allow memory to be allocated by the "Vm_BootAlloc" call.  Memory
  123.      * can be allocated by this method until "Vm_Init" is called.  After this
  124.      * then the normal memory allocator must be used.
  125.      */
  126.     if (main_PrintInitRoutines) {
  127.     Mach_MonPrintf("Calling Vm_BootInit().\n");
  128.     }
  129.     Vm_BootInit();
  130.  
  131.     /*
  132.      * Initialize all devices.
  133.      */
  134.     if (main_PrintInitRoutines) {
  135.     Mach_MonPrintf("Calling Dev_Init().\n");
  136.     }
  137.     Dev_Init();
  138.  
  139.     /*
  140.      *  Initialize the mappings of keys to call dump routines.
  141.      *  Must be after Dev_Init. 
  142.      */
  143.     if (main_DoDumpInit) {
  144.     if (main_PrintInitRoutines) {
  145.         Mach_MonPrintf("Calling Dump_Init().\n");
  146.     }
  147.     Dump_Init();
  148.     }
  149.  
  150.     /*
  151.      * Initialize the timer, signal, process, scheduling and synchronization
  152.      * modules' data structures.
  153.      */
  154.     if (main_PrintInitRoutines) {
  155.     Mach_MonPrintf("Calling Proc_Init().\n");
  156.     }
  157.     Proc_Init();
  158.     if (main_PrintInitRoutines) {
  159.     Mach_MonPrintf("Calling Sync_LockStatInit().\n");
  160.     }
  161.     Sync_LockStatInit();
  162.     if (main_PrintInitRoutines) {
  163.     Mach_MonPrintf("Calling Timer_Init().\n");
  164.     }
  165.     Timer_Init();
  166.     if (main_PrintInitRoutines) {
  167.     Mach_MonPrintf("Calling Sig_Init().\n");
  168.     }
  169.     Sig_Init();
  170.     if (main_PrintInitRoutines) {
  171.     Mach_MonPrintf("Calling Sched_Init().\n");
  172.     }
  173.     Sched_Init();
  174.  
  175.     /*
  176.      * Sys_Printfs are not allowed before this point.
  177.      */  
  178.     main_PanicOK++;
  179.     printf("Sprite kernel: %s\n", SpriteVersion());
  180.  
  181.     /*
  182.      * Set up bins for the memory allocator.
  183.      */
  184.     if (main_PrintInitRoutines) {
  185.     Mach_MonPrintf("Calling Fs_Bin\n");
  186.     }
  187.     Fs_Bin();
  188.     if (main_PrintInitRoutines) {
  189.     Mach_MonPrintf("Calling Net_Bin\n");
  190.     }
  191.     Net_Bin();
  192.  
  193.     /*
  194.      * Initialize virtual memory.  After this point must use the normal
  195.      * memory allocator to allocate memory.  If you use Vm_BootAlloc then
  196.      * will get a panic into the debugger.
  197.      */
  198.     if (main_PrintInitRoutines) {
  199.     Mach_MonPrintf("Calling Vm_Init\n");
  200.     }
  201.     Vm_Init();
  202.  
  203.     /*
  204.      * malloc can be called from this point on.
  205.      */
  206.  
  207.     /*
  208.      * Initialize the main process. Must be called before any new 
  209.      * processes are created.
  210.      * Dependencies: Proc_InitTable, Sched_Init, Vm_Init, Mem_Init
  211.      */
  212.     if (main_PrintInitRoutines) {
  213.     Mach_MonPrintf("Calling Proc_InitMainProc\n");
  214.     }
  215.     Proc_InitMainProc();
  216.  
  217.     if (main_PrintInitRoutines) {
  218.     Mach_MonPrintf("Calling Net_Init\n");
  219.     }
  220.     Net_Init();
  221.     /*
  222.      * Initialize the routes.
  223.      */
  224.     if (main_PrintInitRoutines) {
  225.     Mach_MonPrintf("Calling Net_RouteInit\n");
  226.     }
  227.     Net_RouteInit();
  228.  
  229.     /*
  230.      * Enable server process manager.
  231.      */
  232.     if (main_PrintInitRoutines) {
  233.     Mach_MonPrintf("Calling Proc_ServerInit\n");
  234.     }
  235.     Proc_ServerInit();
  236.  
  237.     /*
  238.      * Initialize the recovery module.  Do before Rpc and after Vm_Init.
  239.      */
  240.     if (main_PrintInitRoutines) {
  241.     Mach_MonPrintf("Calling Recov_Init\n");
  242.     }
  243.     Recov_Init();
  244.  
  245.     /*
  246.      * Initialize the data structures for the Rpc system.  This uses
  247.      * Vm_RawAlloc to so it must be called after Vm_Init.
  248.      * Dependencies: Timer_Init, Vm_Init, Net_Init, Recov_Init
  249.      */
  250.     if (main_PrintInitRoutines) {
  251.     Mach_MonPrintf("Calling Rpc_Init\n");
  252.     }
  253.     Rpc_Init();
  254.  
  255.     /*
  256.      * Configure devices that may or may not exist.  This needs to be
  257.      * done after Proc_InitMainProc because the initialization routines
  258.      * use SetJump which uses the proc table entry for the main process.
  259.      */
  260.     if (main_PrintInitRoutines) {
  261.     Mach_MonPrintf("Calling Dev_Config\n");
  262.     }
  263.     Dev_Config();
  264.  
  265.     /*
  266.      * Initialize profiling after the timer and vm stuff is set up.
  267.      * Dependencies: Timer_Init, Vm_Init
  268.      */
  269.     if (main_DoProf) {
  270.     Prof_Init();
  271.     }
  272.     /*
  273.      *  Allow interrupts from now on.
  274.      */
  275.     if (main_PrintInitRoutines) {
  276.     Mach_MonPrintf("Enabling interrupts\n");
  277.     }
  278.     ENABLE_INTR();
  279.  
  280.     if (main_Debug) {
  281.     DBG_CALL;
  282.     }
  283.  
  284.     /*
  285.      * Sleep for a few seconds to calibrate the idle time ticks.
  286.      */
  287.     Sched_TimeTicks();
  288.  
  289.     /*
  290.      * Start profiling, if desired.
  291.      */
  292.     if (main_DoProf) {
  293.         (void) Prof_Start();
  294.     }
  295.  
  296.     /*
  297.      * Do an initial RPC to get a boot timestamp.  This allows
  298.      * servers to detect when we crash and reboot.  This will set the
  299.      * system clock too, although rdate is usually done from user level later.
  300.      */
  301.     if (main_PrintInitRoutines) {
  302.     printf("Call Rpc_Start\n");
  303.     }
  304.     Rpc_Start();
  305.  
  306.     /*
  307.      * Initialize the file system. 
  308.      */
  309.     if (main_PrintInitRoutines) {
  310.     printf("Call Fs_Init\n");
  311.     }
  312.     Fs_Init();
  313.  
  314.     /*
  315.      * Before starting up any more processes get a current directory
  316.      * for the main process.  Subsequent new procs will inherit it.
  317.      */
  318.     if (main_PrintInitRoutines) {
  319.     printf("Call Fs_ProcInit\n");
  320.     }
  321.     Fs_ProcInit();
  322.  
  323. #ifdef TESTING
  324.     device.unit = 0;
  325.     Dev_ConsoleOpen(&device, FS_READ, NIL);
  326.     while (1) {
  327.     char        buf[11];
  328.     int        len;
  329.     Time        time;
  330.  
  331.     time.seconds = 1;
  332.     time.microseconds = 0;
  333.  
  334.     if (Dev_ConsoleRead(&device, 0, 10, buf, &len) == SUCCESS) {
  335.         printf("%s", buf);
  336.     }
  337.     Sync_WaitTime(time);
  338.     }
  339. #endif
  340.  
  341.     if (main_PrintInitRoutines) {
  342.     printf("Bunch of call funcs\n");
  343.     }
  344.     /*
  345.      * Start the clock daemon and the routine that opens up the swap directory.
  346.      */
  347.     Proc_CallFunc(Vm_Clock, (ClientData) NIL, 0);
  348.     Proc_CallFunc(Vm_OpenSwapDirectory, (ClientData) NIL, 0);
  349.  
  350.     /*
  351.      * Start the process that synchronizes the filesystem caches
  352.      * with the data kept on disk.
  353.      */
  354.     Proc_CallFunc(Fsutil_SyncProc, (ClientData) NIL, 0);
  355.  
  356.     /*
  357.      * Create a few RPC server processes and the Rpc_Daemon process which
  358.      * will create more server processes if needed.
  359.      */
  360.     if (main_NumRpcServers > 0) {
  361.     for (i=0 ; i<main_NumRpcServers ; i++) {
  362.         (void) Rpc_CreateServer((int *) &pid);
  363.     }
  364.     }
  365.     (void) Proc_NewProc((Address)(unsigned)(int (*)())Rpc_Daemon, 
  366.             PROC_KERNEL, FALSE, &pid, "Rpc_Daemon");
  367.     if (main_PrintInitRoutines) {
  368.     printf("Creating Proc server procs\n");
  369.     }
  370.  
  371.     /*
  372.      * Create processes  to execute functions.
  373.      */
  374.     for (i = 0; i < proc_NumServers; i++) {
  375.     (void) Proc_NewProc((Address)(unsigned)(int (*)()) Proc_ServerProc,
  376.                 PROC_KERNEL, FALSE,    &pid, "Proc_ServerProc");
  377.     }
  378.  
  379.     /*
  380.      * Create a recovery process to monitor other hosts.  Can't use
  381.      * Proc_CallFunc's to do this because they can be used up waiting
  382.      * for page faults against down servers.  (Alternatively the VM
  383.      * code could be fixed up to retry page faults later instead of
  384.      * letting the Proc_ServerProc wait for recovery.)
  385.      */
  386.     (void) Proc_NewProc((Address) Recov_Proc, PROC_KERNEL, FALSE, &pid,
  387.             "Recov_Proc");
  388.  
  389.     /*
  390.      * Set up process migration recovery management.
  391.      */
  392.     if (main_PrintInitRoutines) {
  393.     printf("Calling Proc_MigInit\n");
  394.     }
  395.     Proc_MigInit();
  396.  
  397.     /*
  398.      * Call the routine to start test kernel processes.
  399.      */
  400.  
  401.     if (main_PrintInitRoutines) {
  402.     printf("Calling Main_HookRoutine\n");
  403.     }
  404.     Main_HookRoutine();
  405.  
  406.     /*
  407.      * Print out the amount of memory used.
  408.      */
  409.     printf("MEMORY %d bytes allocated for kernel\n", 
  410.         vmMemEnd - mach_KernStart);
  411.  
  412.     /*
  413.      * Start up the first user process.
  414.      */
  415.     if (main_PrintInitRoutines) {
  416.     printf("Creating Init\n");
  417.     }
  418.     (void) Proc_NewProc((Address)(unsigned)(int (*)())Init, PROC_KERNEL,
  419.             FALSE, &pid, "Init");
  420.  
  421.     (void) Sync_WaitTime(time_OneYear);
  422.     printf("Main exiting\n");
  423.     Proc_Exit(0);
  424. }
  425.  
  426.  
  427. /*
  428.  *----------------------------------------------------------------------
  429.  *
  430.  * Init --
  431.  *
  432.  *    This routine execs the init program.
  433.  *
  434.  * Results:
  435.  *    This routine only returns an error if the exec failed.
  436.  *
  437.  * Side effects:
  438.  *    The current process image is overlayed by the init process.
  439.  *
  440.  *----------------------------------------------------------------------
  441.  */
  442. static void
  443. Init()
  444. {
  445.     char        *initArgs[10];
  446.     ReturnStatus    status;
  447.     char        argBuffer[256];
  448.     int            argc;
  449.     Fs_Stream        *dummy;
  450.     char        bootCommand[103];
  451.     char        *ptr;
  452.     int            i;
  453.     int            argLength;
  454.  
  455.     if (main_PrintInitRoutines) {
  456.     Mach_MonPrintf("In Init\n");
  457.     }
  458.     bzero(bootCommand, 103);
  459.     argc = Mach_GetBootArgs(8, 256, &(initArgs[2]), argBuffer);
  460.     if (argc>0 && !strcmp(initArgs[argc+1],"-a")) {
  461.     argc--;
  462.     }
  463.     if (argc>0) {
  464.     argLength = (((int) initArgs[argc+1]) + strlen(initArgs[argc+1]) +
  465.             1 - ((int) argBuffer));
  466.     } else {
  467.     argLength = 0;
  468.     }
  469.     if (argLength > 0) {
  470.     initArgs[1] = "-b";
  471.     ptr = bootCommand;
  472.     for (i = 0; i < argLength; i++) {
  473.         if (argBuffer[i] == '\0') {
  474.         *ptr++ = ' ';
  475.         } else {
  476.         *ptr++ = argBuffer[i];
  477.         }
  478.     }
  479.     bootCommand[argLength] = '\0';
  480.     initArgs[2] = bootCommand;
  481.     initArgs[argc + 2] = (char *) NIL;
  482.     } else {
  483.     initArgs[1] = (char *) NIL;
  484.     }
  485.     if (main_AltInit != 0) {
  486.     initArgs[0] = main_AltInit;
  487.     printf("Execing \"%s\"\n", initArgs[0]);
  488.     status = Proc_KernExec(initArgs[0], initArgs);
  489.     printf( "Init: Could not exec %s status %x.\n",
  490.             initArgs[0], status);
  491.     }
  492.     status = Fs_Open(INIT,FS_EXECUTE | FS_FOLLOW, FS_FILE, 0, &dummy);
  493.     if (status != SUCCESS) {
  494.     printf("Can't open %s <0x%x>\n", INIT,status);
  495.     }
  496.     initArgs[0] = INIT;
  497.     status = Proc_KernExec(initArgs[0], initArgs);
  498.     printf( "Init: Could not exec %s status %x.\n",
  499.             initArgs[0], status);
  500.     Proc_Exit(1);
  501. }
  502.  
  503. TestEther()
  504. {
  505.     extern Boolean    dbg_UsingNetwork;
  506.  
  507.     dbg_UsingNetwork = TRUE;
  508.  
  509.     while (1) {
  510.     Net_RecvPoll();
  511.     }
  512. }
  513.